package com.jsb.laundry.controller.shops;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.github.pagehelper.PageHelper;
import com.jsb.laundry.common.config.Constant;
import com.jsb.laundry.common.enums.ReturnStatusCode;
import com.jsb.laundry.common.exception.BusinessException;
import com.jsb.laundry.common.response.WebResponse;
import com.jsb.laundry.common.utils.BCUtil;
import com.jsb.laundry.common.utils.CodeUtil;
import com.jsb.laundry.common.utils.JSBUtil;
import com.jsb.laundry.common.utils.aliyun.AliOSSUtil;
import com.jsb.laundry.common.utils.http.EncryptUtil;
import com.jsb.laundry.common.utils.jhh.Withdrawal;
import com.jsb.laundry.common.utils.redis.RedisUtil;
import com.jsb.laundry.dao.shops.LaundryShopsDao;
import com.jsb.laundry.model.shops.*;
import com.jsb.laundry.service.shops.LaundryShopsService;
import com.jsb.laundry.service.shops.impl.WithdrawalService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 洗衣小站、旗舰店
 */
@Api(tags = {"洗衣小站、旗舰店"})
@RestController
@RequestMapping("/laundryShops")
public class ShopsController {
    private static final Logger LOGGER = LoggerFactory.getLogger(ShopsController.class);

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private LaundryShopsDao laundryShopsDao;

    @Resource
    private LaundryShopsService laundryShopsService;

    @Resource
    private WithdrawalService withdrawalService;


    /**
     * 店铺、旗舰店 账号密码登录(phone、phoneCode | )
     *
     * @param merchantsInfo
     * @return
     */
    @ApiOperation(value = "店铺、旗舰店 账号密码登录", notes = "店铺、旗舰店 账号密码登录", httpMethod = "POST")
    @PostMapping("/login")
    public WebResponse login(@RequestBody MerchantsInfo merchantsInfo) {
        if (JSBUtil.isEmptyString(merchantsInfo.getPhone()) || JSBUtil.isEmptyString(merchantsInfo.getPhoneCode())) {
            return WebResponse.failOfParameter();
        }
        MerchantsInfo var0 = laundryShopsDao.getMerchantsInfo(merchantsInfo);
        if (var0 == null) {
            return WebResponse.success(ReturnStatusCode.PLEASE_SET_IN.getCode(), ReturnStatusCode.PLEASE_SET_IN.getMsg());
        }
        // 验证验证码是否有效 (白名单、通用验证码888888)
        Object cacheObject = redisUtil.getCacheObject("shopsVerCode:" + merchantsInfo.getPhone()) == null ? "888888" : redisUtil.getCacheObject("shopsVerCode:" + merchantsInfo.getPhone());
        if (cacheObject == null) {
            return WebResponse.success(ReturnStatusCode.VER_CODE_EXPIERED.getCode(), ReturnStatusCode.VER_CODE_EXPIERED.getMsg());
        }
        if (!merchantsInfo.getPhoneCode().equals(String.valueOf(cacheObject))) {
            return WebResponse.success(ReturnStatusCode.VER_CODE_ERROR.getCode(), ReturnStatusCode.VER_CODE_ERROR.getMsg());
        }

        //获取账号下的店铺信息
        Shops shops = laundryShopsDao.getShopsInfo(merchantsInfo);
        if (shops == null) {
            return WebResponse.success(ReturnStatusCode.ACCOUNT_NOTFOUND_SHOPS.getCode(), ReturnStatusCode.ACCOUNT_NOTFOUND_SHOPS.getMsg());
        }

        //token过期时间戳
        long tokenExpireTimestamp = LocalDateTime.now().plusDays(30).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        //TODO token生成处(uuid + userId() + timestamp(token过期的时间戳) )
        String token = "shops_Authorization: " + JSBUtil.generateUUID() + ". " + EncryptUtil.Base64Tool.base64Encode(shops.getShopsId()) + ". " + EncryptUtil.Base64Tool.base64Encode(String.valueOf(tokenExpireTimestamp));
        //存在redis数据库
        redisUtil.setCacheObject(token, shops.getShopsId(), 30, TimeUnit.DAYS);

        shops.setToken(token);
        return WebResponse.successData(shops);
    }

    /**
     * 发送验证码(phone)
     *
     * @param merchantsInfo
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "发送验证码", notes = "发送验证码", httpMethod = "POST")
    @PostMapping("/verCode")
    public WebResponse verCode(@RequestBody MerchantsInfo merchantsInfo) {
        if (JSBUtil.isEmptyString(merchantsInfo.getPhone())) {
            return WebResponse.failOfParameter();
        }
        if (!JSBUtil.isValidPhoneNumber(merchantsInfo.getPhone())) {
            return WebResponse.success(ReturnStatusCode.PHONE_CODE_RE_ERRORS.getCode(), ReturnStatusCode.PHONE_CODE_RE_ERRORS.getMsg());
        }
        MerchantsInfo var0 = laundryShopsDao.getMerchantsInfo(merchantsInfo);
        //判断该手机号是否存在
        if (var0 == null || var0.getPhone() == null) {
            return WebResponse.success(ReturnStatusCode.PLEASE_SET_IN.getCode(), ReturnStatusCode.PLEASE_SET_IN.getMsg());
        }
        //随机6位验证码
        String phoneCode = JSBUtil.getRandomNumberStr(6);

        //发送验证码
        CodeUtil.EndCode(var0.getPhone(), phoneCode);
        //验证码5分钟有效，存入redis中
        redisUtil.setCacheObject("shopsVerCode:" + merchantsInfo.getPhone(), phoneCode, 5, TimeUnit.MINUTES);

        return WebResponse.success();
    }

    /**
     * 第一个方向 订单入店铺表 jsb_orders_shop、jsb_orders_shop_item ( 骑手点确认送达 orderId )
     */
    @ApiOperation(value = "订单入店铺", notes = "订单入店铺", httpMethod = "POST")
    @PostMapping("/orderEnterShops")
    public WebResponse orderEnterShops(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getOrderId())) {
            return WebResponse.failOfParameter();
        }
        int res = laundryShopsService.orderEnterShops(shopOrder);
        return WebResponse.successData(res);
    }

    /**
     * 第一个方向 订单入店铺表（旗舰店入库的） jsb_orders_shop、jsb_orders_shop_item ( 司机点确认送达 subOrderIds:[] )
     */
    @ApiOperation(value = "订单入店铺", notes = "订单入店铺", httpMethod = "POST")
    @PostMapping("/orderEnterShopsPlus")
    public WebResponse orderEnterShopsPlus(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyCollection(shopOrder.getSubOrderIds())) {
            return WebResponse.failOfParameter();
        }
        int res = laundryShopsService.orderEnterShopsPlus(shopOrder);
        return WebResponse.successData(res);
    }


    /**
     * 第二个方向 订单入店铺表 jsb_orders_shop、jsb_orders_shop_item ( 司机点确认送达 subOrderIds:[] )
     */
    @ApiOperation(value = "订单入店铺", notes = "订单入店铺", httpMethod = "POST")
    @PostMapping("/orderEnterShopsBack")
    public WebResponse orderEnterShopsBack(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyCollection(shopOrder.getSubOrderIds())) {
            return WebResponse.failOfParameter();
        }
        int res = laundryShopsService.orderEnterShopsBack(shopOrder);
        return WebResponse.successData(res);
    }


//================================================入库、出库、订单 管理============================================================================//

    /**
     * 获取订单列表(pageNum\pageSize)
     */
    @ApiOperation(value = "获取订单列表", notes = "获取订单列表", httpMethod = "POST")
    @PostMapping("/getShopsOrderList")
    public WebResponse getShopsOrderList(@RequestBody ShopOrderVo shopOrder) {
        if (("1".equals(shopOrder.getShopOrdersStatus()) || "2".equals(shopOrder.getShopOrdersStatus()) || "3".equals(shopOrder.getShopOrdersStatus()) || "4".equals(shopOrder.getShopOrdersStatus()))
                && JSBUtil.isEmptyString(shopOrder.getTrackingDirection())) {
            return WebResponse.failOfParameter();
        }
        if (JSBUtil.isEmptyString(shopOrder.getUid())) {
            return WebResponse.failOfParameter();
        }
        Shops shops = laundryShopsDao.getShopsInfo1(shopOrder.getUid());
        shopOrder.setShopFlag(shops.getShopsType());


        //开启分页
        PageHelper.startPage(shopOrder.getPageNum(), shopOrder.getPageSize());
        List<ShopOrderVo> res = laundryShopsDao.getShopsOrderList(shopOrder);

        return WebResponse.successData(res);
    }

    /**
     * 订单详情( orderId\trackingDirection )
     */
    @ApiOperation(value = "订单详情", notes = "订单详情", httpMethod = "POST")
    @PostMapping("/getShopsOrderDetail")
    public WebResponse getShopsOrderDetail(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getOrderId()) || JSBUtil.isEmptyString(shopOrder.getTrackingDirection())) {
            return WebResponse.failOfParameter();
        }
        ShopOrderDetailVo shopOrderDetailVo = new ShopOrderDetailVo();
        ShopOrderDetailVo.OrderInfo orderInfo = laundryShopsDao.getShopsOrderDetail1(shopOrder);
        List<ShopOrderDetailVo.TransportInfo> transportInfo = laundryShopsDao.getShopsOrderDetail2(shopOrder);
        shopOrderDetailVo.setOrderInfo(orderInfo).setTransportInfo(transportInfo);
        return WebResponse.successData(shopOrderDetailVo);
    }

    /**
     * 运单详情( transportId\trackingDirection )
     */
    @ApiOperation(value = "运单详情", notes = "运单详情", httpMethod = "POST")
    @PostMapping("/getShopsTransportOrderDetail")
    public WebResponse getShopsTransportOrderDetail(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getTransportId()) || JSBUtil.isEmptyString(shopOrder.getTrackingDirection())) {
            return WebResponse.failOfParameter();
        }
        ShopTransportOrderDetailVo shopTransportOrderDetailVo = new ShopTransportOrderDetailVo();
        ShopTransportOrderDetailVo.OrderInfo orderInfo = laundryShopsDao.getShopsTransportOrderDetail1(shopOrder);
        ShopTransportOrderDetailVo.UserInfo userInfo = laundryShopsDao.getShopsTransportOrderDetail2(shopOrder);
        ShopTransportOrderDetailVo.RiderInfo riderInfo = laundryShopsDao.getShopsTransportOrderDetail3(shopOrder);
        ShopTransportOrderDetailVo.ProductInfo productInfo = laundryShopsDao.getShopsTransportOrderDetail4(shopOrder);

        shopTransportOrderDetailVo.setOrderInfo(orderInfo).setUserInfo(userInfo).setRiderInfo(riderInfo).setProductInfo(productInfo);
        return WebResponse.successData(shopTransportOrderDetailVo);
    }


    /**
     * 批量出库入库检查页面数据 ( subOrderIds:[] ,trackingDirection="")
     */
    @ApiOperation(value = "批量出库入库检查页面", notes = "批量出库入库检查页面", httpMethod = "POST")
    @PostMapping("/batchShopsOrderPageData")
    public WebResponse batchShopsOrderPageData(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getUid()) || JSBUtil.isEmptyCollection(shopOrder.getSubOrderIds()) || JSBUtil.isEmptyString(shopOrder.getTrackingDirection())) {
            return WebResponse.failOfParameter();
        }
        BatchOPShopsOrderVo batchOPShopsOrderVo = new BatchOPShopsOrderVo();
        List<BatchOPShopsOrderVo.ProductInfo> productInfoList = laundryShopsDao.batchShopsOrderPageData1(shopOrder);
        BatchOPShopsOrderVo.OPConfirm opConfirm = laundryShopsDao.batchShopsOrderPageData2(shopOrder);

        List<BatchOPShopsOrderVo.OrderOPRecords> orderOPRecordsList = laundryShopsDao.getOrderOPRecordList(shopOrder);

        orderOPRecordsList.forEach(orderOPRecords ->
                productInfoList.stream()
                        .filter(productInfo -> orderOPRecords.getSubOrderId().equals(productInfo.getSubOrderId()))
                        .findFirst()
                        .ifPresent(productInfo -> productInfo.getOrderOPRecordList().add(orderOPRecords))
        );

        batchOPShopsOrderVo.setOpConfirm(opConfirm).setProductInfoList(productInfoList);
        return WebResponse.successData(batchOPShopsOrderVo);
    }

    /**
     * 批量出库入库状态调整 in_check\out_check 检查操作、更新图片等(检查、上传图片)
     */
    @ApiOperation(value = "批量出库入库状态调整", notes = "批量出库入库状态调整", httpMethod = "POST")
    @PostMapping("/updShopsOrderStatus")
    public WebResponse updShopsOrderStatus(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyCollection(shopOrder.getSubOrderIds())
                || JSBUtil.isEmptyString(shopOrder.getTrackingDirection())
                || JSBUtil.isEmptyString(shopOrder.getOpAccount())) {
            return WebResponse.failOfParameter();
        }
        WebResponse response = laundryShopsService.updShopsOrderStatus(shopOrder);
        return response;
    }

    /**
     * 确认批量 出库入库 状态调整（确认 出库入库 ）
     * subOrderIds、trackingDirection、inCheckStatus|outCheckStatus
     */
    @ApiOperation(value = "批量确认 出库入库 状态调整", notes = "批量确认 出库入库 状态调整", httpMethod = "POST")
    @PostMapping("/confirmShopsOrder")
    public WebResponse confirmShopsOrder(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyCollection(shopOrder.getSubOrderIds()) || JSBUtil.isEmptyString(shopOrder.getTrackingDirection())
                || JSBUtil.isEmptyString(shopOrder.getInCheckStatus())
                || JSBUtil.isEmptyString(shopOrder.getOutCheckStatus())
                || JSBUtil.isEmptyString(shopOrder.getUid())) {
            return WebResponse.failOfParameter();
        }
        WebResponse response = laundryShopsService.confirmShopsOrder(shopOrder);
        return response;
    }

//================================================小站 管理============================================================================//

    /**
     * 小站管理列表
     */
    @ApiOperation(value = "小站管理列表", notes = "小站管理列表", httpMethod = "POST")
    @PostMapping("/getShopsManagerList")
    public WebResponse getShopsManagerList(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getUid())) {
            return WebResponse.failOfParameter();
        }

        //开启分页
        PageHelper.startPage(shopOrder.getPageNum(), shopOrder.getPageSize());

        List<Shops> response = laundryShopsDao.getShopsManagerList(shopOrder);

        return WebResponse.successData(response);
    }

    /**
     * 小站管理详情(shopsId\settlementStatus\shopsViewFlag)
     */
    @ApiOperation(value = "小站管理详情", notes = "小站管理详情", httpMethod = "POST")
    @PostMapping("/getShopsManagerDetail")
    public WebResponse getShopsManagerDetail(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getShopsId()) || JSBUtil.isEmptyString(shopOrder.getShopsViewFlag())
                || JSBUtil.isEmptyString(shopOrder.getSettlementStatus())) {
            return WebResponse.failOfParameter();
        }

        ShopsManagerDetailVo response = laundryShopsService.getShopsManagerDetail(shopOrder);

        return WebResponse.successData(response);
    }


    /**
     * 导出数据到excel中 下载
     *
     * @param response
     * @return
     * @throws IOException
     * @RequestBody LinkedHashMap<String, Object> requestData
     */
    @PostMapping(value = "/export")
    public ResponseEntity exportExcel(HttpServletRequest request, HttpServletResponse response) throws IOException {
        ServletInputStream inputStream = request.getInputStream();
        String requestData = JSBUtil.read(inputStream);
        LOGGER.info("ExportExcel数据：{}", requestData);
        JSONObject object = JSONObject.parseObject(requestData, Feature.OrderedField);

        // 解析请求数据
//        JSONObject object = new JSONObject(requestData);

        // 配置信息
        JSONObject excelConfig = object.getJSONObject("excelConfig");
        String fileName = excelConfig.getString("fileName");
        String sheetName = excelConfig.getString("sheetName");
        JSONObject tableFields = excelConfig.getJSONObject("tableFields");

        // 构建响应对象，设置响应头
        response.setContentType("application/octet-stream;application/vnd.ms-excel");//application/vnd.ms-excel;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;application/vnd.ms-excel
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName + ".xls", "UTF-8"));


        if (fileName == null || sheetName == null || tableFields.size() == 0) {
            Map errorObj = new HashMap();
            errorObj.put("code", "10000");
            errorObj.put("message", "请求参数错误");
            return ResponseEntity.status(200).body(errorObj);
        }

        // 获取所有字段的key
        List<String> databaseFields = tableFields.keySet().stream()
                .collect(Collectors.toList());

        // 获取所有字段的值
        List<String> excelColumnLabels = tableFields.values().stream()
                .map(Object::toString)
                .collect(Collectors.toList());

        // 数据信息
        JSONArray dataArray = object.getJSONArray("data");
        if (dataArray == null || dataArray.size() == 0) {
            Map errorObj = new HashMap();
            errorObj.put("code", "10000");
            errorObj.put("message", "导出数据为空");
            return ResponseEntity.status(200).body(errorObj);
        }

        // 创建 Excel 对象
        Workbook workbook = new HSSFWorkbook();
        Sheet sheet = workbook.createSheet(sheetName);

        // 通用、居中对齐的样式
        CellStyle commonStyle = workbook.createCellStyle();
        commonStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); //水平居中
        commonStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); //垂直居中
        commonStyle.setIndention((short) 1); // 设置缩进为1个字符


        // 创建表头样式
        CellStyle headerStyle = workbook.createCellStyle();
        headerStyle.cloneStyleFrom(commonStyle);
        // 字体
        Font headerFont = workbook.createFont();
        headerFont.setFontName("微软雅黑"); // 设置字体名称
        headerFont.setFontHeightInPoints((short) 10); // 设置字体大小
//        headerFont.setBold(true); // 设置是否加粗
        // 将字体应用于样式 - 表头样式
        headerStyle.setFont(headerFont);

        // 创建数据体样式
        CellStyle bodyStyle = workbook.createCellStyle();
        bodyStyle.cloneStyleFrom(commonStyle);
        // 字体
        Font bodyFont = workbook.createFont();
        bodyFont.setFontName("Arial"); // 设置字体名称
        bodyFont.setFontHeightInPoints((short) 10); // 设置字体大小
//        bodyFont.setItalic(true);// 设置斜体
        // 将字体应用于样式 - 数据体样式
        bodyStyle.setFont(bodyFont);


        // 写入列名(表头配置)
        Row headerRow = sheet.createRow(0);
        // 设置行高为 600
        headerRow.setHeight((short) 600);
        int columnIndex = 0;
        for (String label : excelColumnLabels) {
            sheet.autoSizeColumn(columnIndex); //设置单元格大小自适应
            Cell cell = headerRow.createCell(columnIndex++);
            cell.setCellValue(label);
            cell.setCellStyle(headerStyle);
        }


        // 写入数据
        int rowIndex = headerRow.getRowNum() + 1;
        for (int i = 0; i < dataArray.size(); i++) {
            JSONObject dataObject = dataArray.getJSONObject(i);
            Row dataRow = sheet.createRow(rowIndex++);

            // 设置行高为 700
            dataRow.setHeight((short) 700);

            columnIndex = 0;
            for (String key : databaseFields) {
                sheet.autoSizeColumn(columnIndex);//设置单元格大小自适应
                Cell cell = dataRow.createCell(columnIndex++);
                cell.setCellStyle(bodyStyle);
                Object value = dataObject.get(key);
                if (value != null) {
                    cell.setCellValue(value.toString());
                }
            }
        }

        // 设置输出流的格式
        ServletOutputStream os = response.getOutputStream();
        workbook.write(os);
        os.flush();
        os.close();
//    workbook.close();

        return ResponseEntity.ok("OK");
    }


//================================================骑手 管理============================================================================//

    /**
     * 骑手管理列表
     */
    @ApiOperation(value = "骑手管理列表", notes = "骑手管理列表", httpMethod = "POST")
    @PostMapping("/getRiderManagerList")
    public WebResponse getRiderManagerList(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getUid())) {
            return WebResponse.failOfParameter();
        }
        //开启分页
        PageHelper.startPage(shopOrder.getPageNum(), shopOrder.getPageSize());

        List<ShopOrderVo> response = laundryShopsDao.getRiderManagerList(shopOrder);

        return WebResponse.successData(response);
    }

    /**
     * 骑手管理详情(riderId\ settlementStatus\ riderViewFlag)
     */
    @ApiOperation(value = "骑手管理详情", notes = "骑手管理详情", httpMethod = "POST")
    @PostMapping("/getRiderManagerDetail")
    public WebResponse getRiderManagerDetail(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getRiderId()) || JSBUtil.isEmptyString(shopOrder.getRiderViewFlag())
                || JSBUtil.isEmptyString(shopOrder.getSettlementStatus()) || JSBUtil.isEmptyString(shopOrder.getShopFlag())) {
            return WebResponse.failOfParameter();
        }

        RiderManagerDetailVo response = laundryShopsService.getRiderManagerDetail(shopOrder);

        return WebResponse.successData(response);
    }


//================================================客户 管理============================================================================//

    /**
     * 客户管理列表
     */
    @ApiOperation(value = "客户管理列表", notes = "客户管理列表", httpMethod = "POST")
    @PostMapping("/getUserManagerList")
    public WebResponse getUserManagerList(@RequestBody ShopOrderVo shopOrder) {
//        if (JSBUtil.isEmptyString(shopOrder.getShopReferenceCode())) {
//            return WebResponse.failOfParameter();
//        }
        if (JSBUtil.isEmptyString(shopOrder.getUid())) {
            return WebResponse.failOfParameter();
        }
        //开启分页
        PageHelper.startPage(shopOrder.getPageNum(), shopOrder.getPageSize());

        List<ShopOrderVo> response = laundryShopsDao.getUserManagerList(shopOrder);

        return WebResponse.successData(response);
    }

    /**
     * 客户管理详情(userId\settlementStatus\ userViewFlag)
     */
    @ApiOperation(value = "客户管理详情", notes = "客户管理详情", httpMethod = "POST")
    @PostMapping("/getUserManagerDetail")
    public WebResponse getUserManagerDetail(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getUserId()) || JSBUtil.isEmptyString(shopOrder.getUserViewFlag())
                || JSBUtil.isEmptyString(shopOrder.getSettlementStatus())) {
            return WebResponse.failOfParameter();
        }

        UserManagerDetailVo response = laundryShopsService.getUserManagerDetail(shopOrder);

        return WebResponse.successData(response);
    }

    //================================================经营概览-旗舰店============================================================================//

    /**
     * 经营概览-旗舰店
     */
    @ApiOperation(value = "经营概览-旗舰店", notes = "经营概览-旗舰店", httpMethod = "POST")
    @PostMapping("/getShopHome")
    public WebResponse getShopHome(@RequestBody ShopHomeVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getUid())) {
            return WebResponse.failOfParameter();
        }
        ShopHomeVo response = laundryShopsService.getShopHome(shopOrder);
        return WebResponse.successData(response);
    }

    @ApiOperation(value = "经营概览-经营数据", notes = "经营概览-经营数据", httpMethod = "POST")
    @PostMapping("/getShopHomeManageData")
    public WebResponse getShopHomeManageData(@RequestBody ShopHomeVo shopOrder) {
        if (JSBUtil.isEmptyObject(shopOrder.getDataStartTime()) || JSBUtil.isEmptyObject(shopOrder.getDataEndTime())) {
            return WebResponse.failOfParameter();
        }
        ShopHomeVo response = laundryShopsService.getShopHomeManageData(shopOrder);
        return WebResponse.successData(response);
    }

    @ApiOperation(value = "经营概览-增长趋势", notes = "经营概览-增长趋势", httpMethod = "POST")
    @PostMapping("/getShopHomeIncreaseTrend")
    public WebResponse getShopHomeIncreaseTrend(@RequestBody ShopHomeVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getIncreaseTrendIndex())
                || JSBUtil.isEmptyObject(shopOrder.getIncreaseStartTime()) || JSBUtil.isEmptyObject(shopOrder.getIncreaseEndTime())) {
            return WebResponse.failOfParameter();
        }
        ShopHomeVo response = laundryShopsService.getShopHomeIncreaseTrend(shopOrder);
        return WebResponse.successData(response);
    }


    //================================================资金管理============================================================================//

    /**
     * 第三方实名认证接口
     * realName\ userIdNumber\ userPhone\ bankName \ bankCardId \ idNumberFront \ idNumberReverse
     *
     * @param shopsBankCard
     * @return
     */
    @PostMapping("realNameAuthJHH")
    public WebResponse realNameAuthJHH(@RequestBody ShopsBankCard shopsBankCard) {
        if (JSBUtil.isEmptyString(shopsBankCard.getUserIdNumber()) || JSBUtil.isEmptyString(shopsBankCard.getRealName()) || JSBUtil.isEmptyString(shopsBankCard.getUserPhone())
                || JSBUtil.isEmptyString(shopsBankCard.getBankName())
                || JSBUtil.isEmptyString(shopsBankCard.getBankCardId()) || JSBUtil.isEmptyString(shopsBankCard.getIdNumberFront()) || JSBUtil.isEmptyString(shopsBankCard.getIdNumberReverse())) {
            return WebResponse.failOfParameter();
        }
        /**
         * 一个店铺只能绑定一张卡
         */
        ShopsBankCard count = laundryShopsDao.getShopBankCard(shopsBankCard);
        if (!JSBUtil.isEmptyObject(count)) {
            return WebResponse.success(ReturnStatusCode.BINDING_BANK.getCode(), ReturnStatusCode.BINDING_BANK.getMsg());
        }

        /**
         * 添加用户填写的银行卡信息
         */
        Integer id = laundryShopsDao.addShopBankCard(shopsBankCard);
        if (id == null || id == 0) {
            WebResponse.success(ReturnStatusCode.SHOP_ADD_BANK_CARD_FAIL.getCode(), ReturnStatusCode.SHOP_ADD_BANK_CARD_FAIL.getMsg());
        }
        /**
         * TODO 调用第三方绑定信息
         */
        String s = Withdrawal.realName(shopsBankCard.getUserIdNumber(), shopsBankCard.getRealName(), shopsBankCard.getUserPhone(), shopsBankCard.getBankCardId(), shopsBankCard.getIdNumberFront(), shopsBankCard.getIdNumberReverse());
        LOGGER.info("接好活第三方实名认证接口,入参:{},第三方返回结果:{}", shopsBankCard, s);

        //实名认证返回解析
        JSONObject jsonObject = JSONObject.parseObject(s);
        Integer status = jsonObject.getInteger("status");
        Integer realStatus = jsonObject.getInteger("real_status");
        String resultMsg = jsonObject.getString("msg");

        //{"msg":"身份证照片不清晰，请重新上传","param":"","status":-19,"real_status":-191}
        String authStatus = "";
        HashMap map = new HashMap();
        if (status == 200 && realStatus == 200) {
            authStatus = "1"; //实名认证成功
        } else {
            authStatus = "2"; //实名认证失败
        }
        if ("该员工已实名认证成功".equals(resultMsg)) {
            realStatus = -1;
            authStatus = "3";
            resultMsg = "该身份证已认证,请联系聚洗衣客服";
        }

        /**
         * 更新银行卡实名信息
         */
        int var1 = laundryShopsDao.updShopBankCardAuthStatus(shopsBankCard.getId(), authStatus, resultMsg);
        if (var1 == 0) {
            return WebResponse.success(ReturnStatusCode.SHOP_ADD_BANK_CARD_FAIL.getCode(), ReturnStatusCode.SHOP_ADD_BANK_CARD_FAIL.getMsg());
        }
        return WebResponse.successData(String.valueOf(realStatus), resultMsg, map);
    }

    /**
     * 店铺提现 ( 绑定银行卡直接到账 ) 【绑定银行卡账户id、提现金额】
     *
     * @param shopsBankCard
     * @return
     */
    @PostMapping("shopEmbody")
    @Transactional
    public WebResponse shopEmbody(@RequestBody ShopsBankCard shopsBankCard) {
        if (JSBUtil.isEmptyString(shopsBankCard.getUid()) || JSBUtil.isEmptyObject(shopsBankCard.getId())
                || JSBUtil.isEmptyObject(shopsBankCard.getCurrentTXMoney())) {
            return WebResponse.failOfParameter();
        }

        /**
         * 检查用户银行卡信息
         */
        ShopsBankCard bankCardInfo = laundryShopsDao.checkShopsBankCard(shopsBankCard);
        if (bankCardInfo == null) {
            return WebResponse.success(ReturnStatusCode.SHOP_TX_BANK_CARD_FAIL.getCode(), ReturnStatusCode.SHOP_TX_BANK_CARD_FAIL.getMsg());
        }
        //校验提现金额
        if (shopsBankCard.getCurrentTXMoney() <= 0 || shopsBankCard.getCurrentTXMoney() * 100 > bankCardInfo.getAccountAmount()) {
            return WebResponse.success(ReturnStatusCode.SHOP_TX_BANK_CARD_BALANCE_FAIL.getCode(), ReturnStatusCode.SHOP_TX_BANK_CARD_BALANCE_FAIL.getMsg());
        }

        /**
         * 添加提现记录
         */
        String currentTXStr = JSBUtil.turnIntegerStr(String.valueOf(shopsBankCard.getCurrentTXMoney()));
        int currentTXM = (int) (shopsBankCard.getCurrentTXMoney() * Constant.withdrawal_rate * 100); //提现手续费金额
        Withdrawals withdrawal = new Withdrawals();

        withdrawal.setWithdrawalNo("SHOP-TX-" + JSBUtil.generateLongOrderNO())
                .setUserId(shopsBankCard.getUid())
                .setAmount(Integer.parseInt(currentTXStr)) //当前提现金额
                .setSource("3")
                .setWithdrawalType("2")
                .setBankName(bankCardInfo.getBankName())
                .setBankCardNumber(bankCardInfo.getBankCardId())
                .setCommissionAmount(currentTXM) //提现手续费金额
                .setCommissionRate(Constant.withdrawal_rate) //手续费率
        ;
        int txRecords = laundryShopsDao.addWithdrawalRecords(withdrawal);
        if (txRecords == 0) {
            LOGGER.info("提现记录添加失败,{}",withdrawal);
            throw new BusinessException("50001","提现记录添加失败");
        }
        /**
         * 扣除账户金额、添加待结算记录
         */
        withdrawalService.splitSettled(withdrawal.getWithdrawalNo(), withdrawal.getUserId());

//
//        /**
//         * 调用系统分账，扣除账户金额
//         */
//


        /**
         * TODO 调用第三方接口进行提现
         */
//        String withdrawal = Withdrawal.withdrawal(bankCardInfo.getBankCardId(), bankCardInfo.getBankName(), bankCardInfo.getRealName(), bankCardInfo.getUserPhone(), shopsBankCard.getCurrentTXMoney(), bankCardInfo.getUserIdNumber());
//        LOGGER.info("接好活第三方提现接口,入参:{},第三方返回结果:{}", shopsBankCard, withdrawal);
        return WebResponse.success();
    }


    /**
     * 资金管理
     *
     * @param shopsBankCard
     * @return
     */
    @PostMapping("fundManageHome")
    public WebResponse fundManageHome(@RequestBody ShopsBankCard shopsBankCard) {
        FundManageHomeVo vo = laundryShopsService.fundManageHome(shopsBankCard);
        return WebResponse.successData(vo);
    }

    /**
     * 账单管理 (settleFlag|accountFlag)
     */
    @PostMapping("fundManageDetail")
    public WebResponse fundManageDetail(@RequestBody FundManageDetailVo shopsBankCard) {
        if (JSBUtil.isEmptyString(shopsBankCard.getUid()) || JSBUtil.isEmptyString(shopsBankCard.getAccountFlag())
                || JSBUtil.isEmptyString(shopsBankCard.getSettleFlag())) {
            return WebResponse.failOfParameter();
        }
        Object vo = laundryShopsService.fundManageDetail(shopsBankCard);
        return WebResponse.successData(vo);
    }

    /**
     * 水洗标生成条形码( subOrderIds )
     *
     * @param shopOrderVo
     * @return
     */
    @PostMapping("washLabelBCCode")
    public WebResponse washLabelBCCode(@RequestBody ShopOrderVo shopOrderVo) {
        if (JSBUtil.isEmptyString(shopOrderVo.getUid()) || JSBUtil.isEmptyCollection(shopOrderVo.getSubOrderIds())) {
            return WebResponse.failOfParameter();
        }

        List<String> subOrderIds = shopOrderVo.getSubOrderIds();
        List<MultipartFile> files = new ArrayList();
        for (String subOrderId : subOrderIds) {
            BufferedImage bufferedImage = BCUtil.getBarCodeWithWords(subOrderId, subOrderId);
            MultipartFile multipartFile = BCUtil.convertToMultipartFile(bufferedImage);
            files.add(multipartFile);
        }
        List<String> imgUrlList = AliOSSUtil.batchUploadImg(files, "shopPrintWashLabel");

        return WebResponse.successData(imgUrlList);
    }

    //===============================================异常单======================================================================
    @ApiOperation(value = "获取异常单列表", notes = "获取异常单列表", httpMethod = "POST")
    @PostMapping("/getShopsExceptionOrderList")
    public WebResponse getShopsExceptionOrderList(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getUid()) || JSBUtil.isEmptyString(shopOrder.getShopOrdersStatus())) {
            return WebResponse.failOfParameter();
        }

        //开启分页
        PageHelper.startPage(shopOrder.getPageNum(), shopOrder.getPageSize());

        List<ShopOrderVo> res = laundryShopsDao.getShopsExceptionOrderList(shopOrder);

        return WebResponse.successData(res);
    }

    /**
     * 批量异常件出库入库检查页面数据 ( subOrderId:"")
     */
    @ApiOperation(value = "批量出库入库检查页面", notes = "批量出库入库检查页面", httpMethod = "POST")
    @PostMapping("/batchShopsExceptionOrderPageData")
    public WebResponse batchShopsExceptionOrderPageData(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getSubOrderId()) || JSBUtil.isEmptyString(shopOrder.getUid())) {
            return WebResponse.failOfParameter();
        }
        JsbOrderException orderException = laundryShopsDao.batchShopsExceptionOrderPageData(shopOrder);
        return WebResponse.successData(orderException);
    }

    /**
     * subOrderId\operatorAccount
     * 批量出库入库状态调整 exception_check_status 检查操作、更新图片等(检查、上传图片)
     */
    @ApiOperation(value = "批量出库入库状态调整", notes = "批量出库入库状态调整", httpMethod = "POST")
    @PostMapping("/updShopsExceptionOrderStatus")
    public WebResponse updShopsExceptionOrderStatus(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getSubOrderId())
                || JSBUtil.isEmptyString(shopOrder.getOpAccount())) {
            return WebResponse.failOfParameter();
        }
        int var0 = laundryShopsDao.updShopsExceptionOrderStatus(shopOrder);
        return WebResponse.successData(var0);
    }

    /**
     * 异常件 确认入库 状态调整（确认 出库入库 ）
     * subOrderId
     */
    @ApiOperation(value = "批量确认 出库入库 状态调整", notes = "批量确认 出库入库 状态调整", httpMethod = "POST")
    @PostMapping("/confirmShopsExceptionOrder")
    @Transactional
    public WebResponse confirmShopsExceptionOrder(@RequestBody ShopOrderVo shopOrder) {
        if (JSBUtil.isEmptyString(shopOrder.getSubOrderId()) || JSBUtil.isEmptyString(shopOrder.getUid())) {
            return WebResponse.failOfParameter();
        }
        // 把 jsb_orders_shop_item 中shop_orders_item_status=2
        int var0 = laundryShopsDao.updShopsExceptionOrderStatus1(shopOrder);
        // 把jsb_orders_driver_item中 exception_status=0
        int var1 = laundryShopsDao.updShopsExceptionOrderStatus2(shopOrder);

        if (var0 == 0 || var1 == 0) {
            return WebResponse.successData(0);
        }
        return WebResponse.successData(1);
    }


}
